package com.hui.realm;

import com.hui.entity.User;
import com.hui.service.ResourceService;
import com.hui.service.RoleService;
import com.hui.service.UserRoleService;
import com.hui.service.UserService;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;


/**
 * 用户登录授权
 */
public class UserRealm extends AuthorizingRealm {
    private static final Logger logger = Logger.getLogger(UserRealm.class);

    @javax.annotation.Resource
    private UserRoleService userRoleService;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    /**
     * 用户授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        //直接调用getPrimaryPrincipal得到之前传入的用户名  
        User user = (User) principals.getPrimaryPrincipal();
        logger.info("[用户:" + user.getUsername() + "|权限授权]");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //根据用户名调用UserService接口获取角色及权限信息
        authorizationInfo.setRoles(roleService
                .loadRoleIdByUsername(user.getUsername()));
        authorizationInfo.setStringPermissions(resourceService
                .loadPermissionsByUsername(user.getUsername()));//获取到权限。放到authorizationInfo中
        logger.info("[用户:" + user.getUsername() + "|权限授权完成]");
        return authorizationInfo;
    }

    /**
     * 验证用户的密码
     */
    @Override
    public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        // 获取基于用户名和密码的令牌  
        // 实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的  
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = (String) token.getPrincipal();
        System.out.println("pwd:" + token.getCredentials().toString());
        logger.info("[用户:" + username + "|系统权限认证]");
        User u = new User();
        u.setUsername(username);
        List<User> list = userService.find(u);
        if (list.size() > 0) {
            User sqluser = list.get(0);
            // 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现  
            System.out.println("Realm:" + ByteSource.Util.bytes(sqluser.getCredentialsSalt()));
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(sqluser, sqluser.getPassword(),
                    ByteSource.Util.bytes(sqluser.getCredentialsSalt()), this.getName());// realm
            logger.info("[用户:" + username + "|系统权限认证完成]");
            return authenticationInfo;
        }
        return null;
    }
}  